iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0

延續昨天補位的情境,我們今天要來實作一下補位的範例,同樣以官方提供的範例碼,由筆者加上註解與 debuf log 編譯完成後,放到 docker hub 上提供大家體驗看看,請使用這份 backfill.yaml 部署,裏面使用的是註解過後的 MMF

範例解析

同基本範例兩人成團的情境,本次若在第一時間不足兩人時,會產生一個補位的 backfill

https://i.imgur.com/8Eeaeec.gif

QueryPool

這部分跟原本不同的地方在於,除了呼叫 matchfunction.QueryPool 以外, 還需要確認補問的部分,因此需要額外呼叫 matchfunction.QueryBackfillPool ,來帶入我們的配對邏輯 makeMatches 中。

func (s *matchFunctionService) Run(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error {
	log.Printf("Generating proposals for function %v", req.GetProfile().GetName())

	var proposals []*pb.Match
	profile := req.GetProfile()
	pools := profile.GetPools()

	for _, p := range pools {
		tickets, err := matchfunction.QueryPool(stream.Context(), s.queryServiceClient, p)
		if err != nil {
			log.Printf("Failed to query tickets for the given pool, got %s", err.Error())
			return err
		}

		backfills, err := matchfunction.QueryBackfillPool(stream.Context(), s.queryServiceClient, p)
		if err != nil {
			log.Printf("Failed to query backfills for the given pool, got %s", err.Error())
			return err
		}

		for i := range backfills {
			log.Printf("QueryBackfillPool get backfill_id: %s\n", backfills[i].Id)
		}

		matches, err := makeMatches(profile, p, tickets, backfills)
		if err != nil {
			log.Printf("Failed to generate matches, got %s", err.Error())
			return err
		}

		proposals = append(proposals, matches...)
	}

	log.Printf("Streaming %v proposals to Open Match", len(proposals))
	// Stream the generated proposals back to Open Match.
	for _, proposal := range proposals {
		if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil {
			log.Printf("Failed to stream proposals to Open Match, got %s", err.Error())
			return err
		}
	}

	return nil
}

makeMatches

這裡是我們實踐補位邏輯的核心,在拿到想要配對的 tickets 與需要補位的數量 backfills 後,我們可以依據我們的配對人數,先將補位的部分處理好,如果補位後還有 tickets 則先配對成新遊戲,若有不足人數時(餘數),則在給予新的 backfill

func makeMatches(profile *pb.MatchProfile, pool *pb.Pool, tickets []*pb.Ticket, backfills []*pb.Backfill) ([]*pb.Match, error) {
	var matches []*pb.Match
	//先將 backfills 裡面的空位填滿
	newMatches, remainingTickets, err := handleBackfills(profile, tickets, backfills, len(matches))
	if err != nil {
		return nil, err
	}

	//持續依照遊戲上線湊滿房間 create normal match
	matches = append(matches, newMatches...)
	newMatches, remainingTickets = makeFullMatches(profile, remainingTickets, len(matches))
	matches = append(matches, newMatches...)

	//餘數沒滿的情況 create match with backfill
	if len(remainingTickets) > 0 {
		match, err := makeMatchWithBackfill(profile, pool, remainingTickets, len(matches))
		if err != nil {
			return nil, err
		}

		matches = append(matches, match)
	}

	return matches, nil
}

可以透過在 MMF 加入的 debug log,來協助我們觀察其補位的過程
https://i.imgur.com/jVj014J.gif


上一篇
Day13 補位策略 Backfill
下一篇
Day15 Open-Match 監控安裝
系列文
徵坦補! 新手可! Open-Match 配對框架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言